package com.coocaa.ops.admin.v1.audit.provider;

import com.coocaa.ops.admin.base.AbstractBizImpl;
import com.coocaa.ops.admin.base.exception.AdminBizException;
import com.coocaa.ops.admin.base.validator.InputParamsValidator;
import com.coocaa.ops.admin.v1.audit.model.ExecutionTaskModel;
import com.coocaa.ops.common.core.base.enums.ResourceStatusEnums;
import com.coocaa.ops.common.core.base.entity.BaseHistoryTableEntity;
import com.coocaa.ops.common.core.base.entity.BaseOriginTableEntity;
import com.coocaa.ops.common.core.base.model.ResourceBaseModel;
import com.coocaa.ops.common.core.base.mybatis.QueryTemplate;
import com.coocaa.ops.common.core.base.util.BeanCopyUtil;
import com.coocaa.ops.common.core.base.util.ResourceStatusValidator;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

/**
 * @author bijiahao
 * @date : 2018/9/10.
 * @description
 */
public abstract class AbstractAuditTaskProviderImpl<T extends BaseOriginTableEntity> extends BaseAuditTaskProviderImpl<T> {

    /**
     * 设置抽象基础业务实现实例
     *
     * @return
     */
    abstract public AbstractBizImpl getAbstractBizImpl();

    /**
     * 上架
     *
     * @param resourceBaseModel
     * @param userId
     */
    @Override
    public void putShelves(ResourceBaseModel resourceBaseModel, Integer userId) {
        //要上线的版本
        Integer toOnLineVersion = resourceBaseModel.getVersion();
        //当前版本信息
        T currentInfo = (T) getAbstractBizImpl().queryById(resourceBaseModel.getId());
        //副本标识
        Integer duplicateVersion = currentInfo.getDuplicateVersion();
        //更新当前版本 对应历史表状态->状态0
        getAbstractBizImpl().updateHistoryStatus(currentInfo.getId(), currentInfo.getCurrentVersion(), userId, ResourceStatusEnums.OFF_LINE.getStatus());
        //更新要上线 对应历史表状态->状态4
        getAbstractBizImpl().updateHistoryStatus(currentInfo.getId(), toOnLineVersion, userId, ResourceStatusEnums.ON_LINE.getStatus());

        //查出要审核的版本记录并更新到原始表中
        BaseHistoryTableEntity historyEntity = getAbstractBizImpl().queryHistoryByIdAndVersion(currentInfo.getId(), toOnLineVersion);
        T update = (T) getAbstractBizImpl().createOriginEntityNewInstance();
        BeanCopyUtil.copyOrig2Target(historyEntity, update, "上架操作历史表复制->原始表实体类！");
        update.setDuplicateVersion(duplicateVersion);
        //创建者不能改变,内容权限控制要使用
        update.setCreator(currentInfo.getCreator());
        //设置当前状态审核通过
        update.setStatus(ResourceStatusEnums.ON_LINE.getStatus());
        getAbstractBizImpl().updateById(update);
    }

    /**
     * 取消定时
     *
     * @param resourceBaseModel
     * @param userId
     */
    @Override
    public void cancelTask(ResourceBaseModel resourceBaseModel, Integer userId) {
        //要取消任务的id
        Integer id = resourceBaseModel.getId();
        //当前版本信息
        T currentInfo = (T) getAbstractBizImpl().queryById(resourceBaseModel.getId());
        if (InputParamsValidator.isDuplicateExist(currentInfo.getDuplicateVersion())) {
            throw new RuntimeException("There is a copy to be reviewed, and the scheduled task can be cancelled after review!");
        }
        //要取消任务的版本
        Integer toCancelVersion = resourceBaseModel.getVersion();
        T updateEntity = (T) getAbstractBizImpl().createOriginEntityNewInstance();
        if (BaseAuditTaskProviderImpl.V_1.equals(toCancelVersion)) {
            //如果取消任务的当前版本为V1 设置原始表对应状态【状态2-草稿】
            updateEntity.setId(id);
            updateEntity.setStatus(ResourceStatusEnums.DRAFT.getStatus());
            updateEntity.setModifier(userId);
            getAbstractBizImpl().updateById(updateEntity);
            //将历史版本删除
            deleteHistory(id, toCancelVersion);
        } else {
            //如果取消任务的当前版本不为V1, 设置历史表对应状态【状态2-草稿】
            getAbstractBizImpl().updateHistoryStatus(id, toCancelVersion, userId, ResourceStatusEnums.DRAFT.getStatus());
            //设置标识位
            updateEntity.setId(id);
            updateEntity.setDuplicateVersion(toCancelVersion);
            updateEntity.setModifier(userId);
            getAbstractBizImpl().updateById(updateEntity);
        }
    }

    /**
     * 审核
     *
     * @param executionTaskModel
     * @param userId
     */
    @Override
    public void auditTask(ExecutionTaskModel executionTaskModel, Integer userId) {
        T currentEntityInfo = (T) getAbstractBizImpl().queryById(executionTaskModel.getId());
        if (InputParamsValidator.isDuplicateExist(currentEntityInfo.getDuplicateVersion())) {
            //如果有副本值
            handleAuditForHasCopyFlag(currentEntityInfo, executionTaskModel.getAuditFlag(), userId);
        } else {
            //如果没有副本值
            handleAuditForNoCopyFlag(currentEntityInfo, executionTaskModel.getAuditFlag(), userId);
        }
    }

    /**
     * 撤销审核
     *
     * @param resourceBaseModel
     * @param userId
     */
    @Override
    public void revokedAudit(ResourceBaseModel resourceBaseModel, Integer userId) {
        T entityDb = (T) getAbstractBizImpl().queryById(resourceBaseModel.getId());
        if (Objects.equals(entityDb.getCurrentVersion(), resourceBaseModel.getVersion()) && ResourceStatusValidator.isOnline(entityDb.getStatus())) {
            //如果不是V1版本，而且和当前版本一样
            throw new AdminBizException("该撤销版本已被审核,不可再撤销!");
        }
        if (BaseAuditTaskProviderImpl.V_1.equals(resourceBaseModel.getVersion())) {
            T update = (T) getAbstractBizImpl().createOriginEntityNewInstance();
            update.setId(resourceBaseModel.getId());
            update.setStatus(ResourceStatusEnums.DRAFT.getStatus());
            update.setModifier(userId);
            //更新为草稿状态
            getAbstractBizImpl().updateById(update);
        } else {
            getAbstractBizImpl().updateHistoryStatus(resourceBaseModel.getId(), resourceBaseModel.getVersion(), userId, ResourceStatusEnums.DRAFT.getStatus());
        }
    }

    protected void handleAuditForHasCopyFlag(T currentEntityInfo, Integer auditFlag, Integer userId) {
        Integer duplicateVersion = currentEntityInfo.getDuplicateVersion();
        //审核历史表中的副本时：先把历史表中对应的旧版本状态设置为下架状态，要审核的记录设置成审核通过
        if (ResourceStatusValidator.isOnline(auditFlag)) {
            T entity = (T) getAbstractBizImpl().createOriginEntityNewInstance();
            //更新当前数据 对应历史表数据状态
            getAbstractBizImpl().updateHistoryStatus(currentEntityInfo.getId(), currentEntityInfo.getCurrentVersion(), auditFlag, ResourceStatusEnums.OFF_LINE.getStatus());
            //查出要审核的版本记录并更新到原始表中
            BaseHistoryTableEntity historyEntity = getAbstractBizImpl().queryHistoryByIdAndVersion(currentEntityInfo.getId(), duplicateVersion);
            BeanCopyUtil.copyOrig2Target(historyEntity, entity, "审核副本历史表复制->原始表实体类！");
            entity.setStatus(ResourceStatusEnums.ON_LINE.getStatus());
            entity.setDuplicateVersion(null);
            //创建者不能改变,内容权限控制要使用
            entity.setCreator(currentEntityInfo.getCreator());
            getAbstractBizImpl().updateById(entity);
        } else {
            //更新副本标识信息
            T update = (T) getAbstractBizImpl().createOriginEntityNewInstance();
            update.setId(currentEntityInfo.getId());
            update.setDuplicateVersion(null);
            getAbstractBizImpl().updateById(update);
        }
        //更新当前数据的对应副本，在历史表的状态
        getAbstractBizImpl().updateHistoryStatus(currentEntityInfo.getId(), duplicateVersion, userId, auditFlag);
    }

    protected void handleAuditForNoCopyFlag(T currentEntityInfo, Integer auditFlag, Integer userId) {
        BaseHistoryTableEntity historyEntity = getAbstractBizImpl().queryHistoryByIdAndVersion(currentEntityInfo.getId(), BaseAuditTaskProviderImpl.V_1);
        if (isInitHistoryVersionForV1(historyEntity, auditFlag)) {
            addHistoryTabForInit(currentEntityInfo, auditFlag, userId);
        }
        T update = (T) getAbstractBizImpl().createOriginEntityNewInstance();
        update.setId(currentEntityInfo.getId());
        update.setStatus(auditFlag);
        getAbstractBizImpl().updateById(update);
    }


    /**
     * 是否初始化V1版本数据
     *
     * @param historyEntity
     * @param auditFlag
     * @return
     */
    protected boolean isInitHistoryVersionForV1(BaseHistoryTableEntity historyEntity, Integer auditFlag) {
        return null == historyEntity && (auditFlag == ResourceStatusEnums.ON_LINE.getStatus() || auditFlag == ResourceStatusEnums.AUDITED_NOT_ON_LINE.getStatus());
    }

    /**
     * 历史表没有记录，而且需要审核通过或者审核通过未上线 将信息备份到历史表
     *
     * @param currentEntityInfo
     * @param status
     * @param auditorId
     */
    protected void addHistoryTabForInit(T currentEntityInfo, Integer status, Integer auditorId) {
        BaseHistoryTableEntity history = getAbstractBizImpl().createHistoryEntityNewInstance();
        BeanCopyUtil.copyOrig2Target(currentEntityInfo, history, "原始表数据复制->历史表实体类");
        history.setStatus(status);
        //创建者不能改变,内容权限控制要使用
        history.setCreator(currentEntityInfo.getCreator());
        history.setModifier(auditorId);
        history.setCurrentVersion(BaseAuditTaskProviderImpl.V_1);
        getAbstractBizImpl().addHistory(history);
    }

    /*************** ===私有方法=== ********************* ===start=== ***************************************/

    private void deleteHistory(Integer id, Integer version) {
        QueryTemplate<T> wrapper = QueryTemplate.getEqQueryTemplate("id", id);
        wrapper.eq("current_version", version);
        if (getAbstractBizImpl().getHistoryMapper().selectCount(wrapper) > 0) {
            getAbstractBizImpl().getHistoryMapper().delete(wrapper);
        }
    }
}
